﻿// ===============================================================================
//  Copyright © ymind.net. All rights reserved .
//  官方网站：http://ymind.net/
//  版权所有：彦铭工作室 老陈出品
// ===============================================================================

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;

namespace Lcsoft.TemplateEngine
{
	/// <summary>
	/// 提供用于 <see cref="Lcsoft.TemplateEngine"/> 的通用方法。无法继承此类。
	/// </summary>
	[ComVisible(true)]
	public static class TemplateEngineHelper
	{
		/// <summary>
		/// 包含当前模板引擎类库的发布日期。
		/// </summary>
		internal static readonly DateTime ProductDate = DateTime.MinValue;

		/// <summary>
		/// 包含当前模板引擎类库的文件版本号。
		/// </summary>
		internal static readonly Version Version = new Version("4.0.0.0");

		private static readonly Converter<string, string> _valueConvert = value =>
		{
			value = value.Replace(" [LT] ", " < ").Replace(" [LTE] ", " <= ");
			value = value.Replace(" [GT] ", " < ").Replace(" [GTE] ", " <= ");
			value = value.Replace("{$", String.Empty).Replace("$}", String.Empty);

			return value;
		};

		/// <summary>
		/// 初始化 <see cref="TemplateEngineHelper"/> 的值。
		/// </summary>
		static TemplateEngineHelper()
		{
			var assembly = Assembly.GetExecutingAssembly();
			var version = "4.0.0.0";
			var fileName = assembly.Location;

			if (String.IsNullOrEmpty(fileName) == false && File.Exists(fileName))
			{
				var fi = FileVersionInfo.GetVersionInfo(fileName);

				if (String.IsNullOrEmpty(fi.FileVersion) == false) version = fi.FileVersion;
			}

			Version = new Version(version);
			ProductDate = new DateTime(2010, 4, 12);
		}

		/// <summary>
		/// 将指定文本转换为 Aspx 代码。
		/// </summary>
		/// <param name="text">要转换的文本。</param>
		/// <returns>返回表示 <paramref name="text"/> 的 Aspx 代码。</returns>
		public static string ConvertToStringFormat(string text)
		{
			var textTrimed = text.Trim();

			if (String.IsNullOrEmpty(textTrimed)) return String.Empty;
			if (textTrimed.StartsWith("<%") && textTrimed.EndsWith("%>")) return text.Remove(text.Length - 2).Remove(text.IndexOf("<%", StringComparison.Ordinal), 2);

			text = text.Replace("</script>", @"<[LCSOFT.TEMPLATEENGINE:AND_DOUBLEQUOTES]/script>");
			text = text.Replace("{", "[LCSOFT.TEMPLATEENGINE:LEFT_BRACE]").Replace("}", "[LCSOFT.TEMPLATEENGINE:RIGHT_BRACE]");
			text = text.Replace("[LCSOFT.TEMPLATEENGINE:LEFT_BRACE]$", "{$").Replace("$[LCSOFT.TEMPLATEENGINE:RIGHT_BRACE]", "$}");

			if (text.IndexOf("{$", StringComparison.Ordinal) == -1 || text.IndexOf("$}", StringComparison.Ordinal) == -1)
			{
				if (text.IndexOf('"') == -1 && text.IndexOf('{') == -1 && text.IndexOf('}') == -1) text = String.Format(@"		document.AppendLine(""{0}"");", text.Replace(@"\", @"\\"));
				else text = String.Format(@"		document.AppendLine(@""{0}"");", text.Replace(@"""", @"""""").Replace("[LCSOFT.TEMPLATEENGINE:LEFT_BRACE]", "{").Replace("[LCSOFT.TEMPLATEENGINE:RIGHT_BRACE]", "}"));
			}
			else
			{
				var tokens = new List<string>();
				var indexStart = text.IndexOf("{$", StringComparison.Ordinal);

				while (indexStart < text.Length && indexStart >= 0)
				{
					var indexEnd = text.IndexOf("$}", indexStart + 2, StringComparison.Ordinal);

					if (indexEnd == -1) break;

					var value = text.Substring(indexStart, indexEnd - indexStart + 2);

					if (tokens.Contains(value) == false) tokens.Add(value);

					indexStart = text.IndexOf("{$", indexEnd + 2, StringComparison.Ordinal);
				}

				tokens.Add("Environment.NewLine");

				indexStart = 0;

				text = tokens.Aggregate(text, (current, token) => current.Replace(token, String.Format("{{{0}}}", indexStart++)));
				text += String.Format("{{{0}}}", indexStart - 1);

				if (text.IndexOf('"') == -1 && text.IndexOf('{') == -1 && text.IndexOf('}') == -1) text = String.Format(@"		document.AppendFormat(""{0}"", {1});", text.Replace(@"\", @"\\"), String.Join(", ", tokens.ConvertAll(_valueConvert).ToArray()));
				else text = String.Format(@"		document.AppendFormat(@""{0}"", {1});", text.Replace(@"""", @"""""").Replace("[LCSOFT.TEMPLATEENGINE:LEFT_BRACE]", "{{").Replace("[LCSOFT.TEMPLATEENGINE:RIGHT_BRACE]", "}}"), String.Join(", ", tokens.ConvertAll(_valueConvert).ToArray()));
			}

			return text.Replace("[LCSOFT.TEMPLATEENGINE:LEFT_BRACE]", "{").Replace("[LCSOFT.TEMPLATEENGINE:RIGHT_BRACE]", "}").Replace("[LCSOFT.TEMPLATEENGINE:AND_DOUBLEQUOTES]", @""" + @""");
		}

		/// <summary>
		/// 获取字符串代表的枚举值。
		/// </summary>
		/// <param name="str">表示枚举项的字符串。</param>
		/// <returns>T</returns>
		public static T GetEnum<T>(string str) { return (T)Enum.Parse(typeof(T), str, true); }

		/// <summary>
		/// 将该字符串文本转换为 Boolean 类型。
		/// </summary>
		/// <param name="str">表示文本，即一系列 Unicode 字符。</param>
		/// <returns>Boolean</returns>
		public static bool ToBoolean(string str) { return !String.IsNullOrEmpty(str) && (String.Compare(str, "true", StringComparison.OrdinalIgnoreCase) == 0 || (String.Compare(str, "yes", StringComparison.OrdinalIgnoreCase) == 0 || str == "1")); }
	}
}
